package com.ruoyi.teacher.service.impl;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.ruoyi.common.core.context.SecurityContextHolder;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.weChatRobot.utils.WechatRobotUtil;
import com.ruoyi.teacher.domain.Teacher;
import com.ruoyi.teacher.domain.TeacherTaskDto;
import com.ruoyi.teacher.mapper.TeacherMapper;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.ruoyi.teacher.mapper.TeacherTaskMapper;
import com.ruoyi.teacher.domain.TeacherTask;
import com.ruoyi.teacher.service.ITeacherTaskService;

/**
 * 领取任务Service业务层处理
 *
 * @author clid
 * @date 2024-03-28
 */
@Service
public class TeacherTaskServiceImpl implements ITeacherTaskService {
    @Autowired
    private TeacherTaskMapper teacherTaskMapper;

    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 查询领取任务
     *
     * @param id 领取任务主键
     * @return 领取任务
     */
    @Override
    public TeacherTask selectTeacherTaskById(Long id) {
        return teacherTaskMapper.selectTeacherTaskById(id);
    }

    /**
     * 查询领取任务列表
     *
     * @param teacherTask 领取任务
     * @return 领取任务
     */
    @Override
    public List<TeacherTask> selectTeacherTaskList(TeacherTask teacherTask) {
        //查询所有完成的任务
        List<TeacherTaskDto> teacherTaskDtos = teacherTaskMapper.selectCompleteTask();
        HashMap<String, Integer> map = new HashMap<>();
        List<Teacher> teachers = teacherMapper.selectTeacherList(new Teacher());
        Map<Long, String> teacherMap = teachers.stream()
                .collect(Collectors.toMap(Teacher::getId, Teacher::getName));

        teacherTaskDtos.forEach(t -> {
            Long teacherId = t.getTeacherId();
            String name = teacherMap.get(teacherId);
            String key = teacherId + "-" + name;
            if (map.containsKey(key)) {
                map.put(key, map.get(key) + 1);
            } else {
                map.put(key, 1);
            }
        });
        redisTemplate.opsForZSet().remove("Teacher-Task-Ranking", "*");
        map.keySet().forEach(k -> {
            Boolean add = redisTemplate.opsForZSet().add("Teacher-Task-Ranking", k, map.get(k));
            System.out.println(add);
        });
        List<TeacherTask> teacherTasks = teacherTaskMapper.selectTeacherTaskList(teacherTask);
        redisTemplate.delete("Teacher-Task-Count");
        redisTemplate.opsForValue().set("Teacher-Task-Count", teacherTasks.size());
        return teacherTasks;
    }

    /**
     * 新增领取任务
     *
     * @param teacherTask 领取任务
     * @return 结果
     */
    @Override
    public int insertTeacherTask(TeacherTask teacherTask) {
        teacherTask.setCreateTime(DateUtils.getNowDate());
        return teacherTaskMapper.insertTeacherTask(teacherTask);
    }

    /**
     * 修改领取任务
     *
     * @param teacherTask 领取任务
     * @return 结果
     */
    @Override
    public int updateTeacherTask(TeacherTask teacherTask) {
        return teacherTaskMapper.updateTeacherTask(teacherTask);
    }

    /**
     * 批量删除领取任务
     *
     * @param ids 需要删除的领取任务主键
     * @return 结果
     */
    @Override
    public int deleteTeacherTaskByIds(Long[] ids) {
        return teacherTaskMapper.deleteTeacherTaskByIds(ids);
    }

    /**
     * 删除领取任务信息
     *
     * @param id 领取任务主键
     * @return 结果
     */
    @Override
    public int deleteTeacherTaskById(Long id) {
        return teacherTaskMapper.deleteTeacherTaskById(id);
    }

    /**
     * 获取任务
     *
     * @param teacherTask 老师任务
     */
    @Override
    public void fetchTask(TeacherTask teacherTask) {
        Long loginId = SecurityContextHolder.getUserId();
        Teacher teacher = teacherMapper.findbyLoginId(String.valueOf(loginId));
        if (teacher == null) {
            throw new RuntimeException("老师不存在");
        }
        //参数校验
        //任务是否存在
        //任务状态是否是可领取
        //任务是否已经到期
        //加锁
        RLock lock = redissonClient.getLock("task-no" + teacherTask.getId());
        if (!lock.tryLock()) {
            throw new RuntimeException("任务已被领取");
        }
        try {
            TeacherTask teacherTaskDb = teacherTaskMapper.selectTeacherTaskById(teacherTask.getId());
            if (teacherTaskDb == null) {
                throw new RuntimeException("任务不存在");
            }
            Long status = teacherTaskDb.getStatus();
            if (!status.equals(0L)) {
                throw new RuntimeException("任务不可领取");
            }
            Date endTime = teacherTaskDb.getEndTime();
            if (!DateUtil.isIn(DateUtil.date(), teacherTaskDb.getCreateTime(), endTime)) {
                throw new RuntimeException("任务已截止");
            }
            TeacherTaskDto teacherTaskDto = new TeacherTaskDto();
            teacherTaskDto.setTaskId(teacherTask.getId());
            teacherTaskDto.setTeacherId(teacher.getId());
            teacherTaskDto.setCollectionTime(DateUtil.date());
            TeacherTaskDto teacherTaskDtoDb = teacherTaskMapper.findCompleteTask(teacherTaskDto);
            if (teacherTaskDtoDb != null) {
                throw new RuntimeException("请勿重复领取任务");
            }
            teacherTaskMapper.insertTeacherTaskRelationship(teacherTaskDto);
            //修改任务次数
            TeacherTask teacherTaskDataBase = teacherTaskMapper.selectTeacherTaskById(teacherTask.getId());
            teacherTaskDataBase.setCount(teacherTaskDataBase.getCount() + 1);
            teacherTaskMapper.updateTeacherTask(teacherTaskDataBase);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("任务领取失败");
        } finally {
            //释放锁
            if (lock.isLocked()) {
                lock.unlock();
            }
        }

    }

    /**
     * 我的任务
     *
     * @param teacherTask 老师任务
     * @return {@link List}<{@link TeacherTask}>
     */
    @Override
    public List<TeacherTaskDto> relationshipList(TeacherTask teacherTask) {
        Long loginId = SecurityContextHolder.getUserId();
        Teacher teacher = teacherMapper.findbyLoginId(String.valueOf(loginId));
        teacherTask.setTaskPersonId(teacher.getId());
        List<TeacherTaskDto> teacherTasks = teacherTaskMapper.selectRelationshipList(teacherTask);
        return teacherTasks;
    }

    /**
     * 教师完成任务
     *
     * @param teacherTaskDto 教师任务
     */
    @Override
    public void teacherCompleteTask(TeacherTaskDto teacherTaskDto) {
        Long id = teacherTaskDto.getId();
        TeacherTaskDto teacherTaskDb = teacherTaskMapper.findTeacherCompleteTask(id);
        if (teacherTaskDb == null) {
            throw new RuntimeException("任务不存在");
        }
        if (!teacherTaskDb.getStatus().equals(0)) {
            throw new RuntimeException("任务状态异常");
        }
        teacherTaskMapper.teacherCompleteTask(teacherTaskDto);
    }

    /**
     * 工作通知
     */
    @Override
    public void workNotification() {
        List<TeacherTaskDto> teacherTaskDtos = teacherTaskMapper.selectTodayRelationshipList();
        if (CollUtil.isEmpty(teacherTaskDtos)) {
            return;
        }
        List<Teacher> teachers = teacherMapper.selectTeacherList(new Teacher());
        Map<Long, String> teacherMap = teachers.stream()
                .collect(Collectors.toMap(Teacher::getId, Teacher::getPhone));
        List<String> phones = teacherTaskDtos.stream()
                .map(t -> {
                    return teacherMap.get(t.getTeacherId());
                }).collect(Collectors.toList());
        WechatRobotUtil.sendTextMessage("有领取任务，请及时完成", phones);
    }

    /**
     * 教师未完成任务
     *
     * @return {@link List}<{@link TeacherTaskDto}>
     */
    @Override
    public List<TeacherTaskDto> teacherUncompletedTask() {
        List<TeacherTaskDto> teacherTaskDtos = relationshipList(new TeacherTask());
        return  teacherTaskDtos.stream().filter(t -> {
            return t.getStatus().equals(0);
        }).collect(Collectors.toList());
    }

}
